/*
 * Copyright (c) 2018, Nordic Semiconductor
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package no.nordicsemi.android.blinky;

import android.app.ProgressDialog;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import butterknife.BindView;
import butterknife.ButterKnife;
import no.nordicsemi.android.ble.data.Data;
import no.nordicsemi.android.blinky.adapter.DiscoveredBluetoothDevice;
import no.nordicsemi.android.blinky.utils.BitmapUtils;
import no.nordicsemi.android.blinky.utils.DataHandlerUtils;
import no.nordicsemi.android.blinky.utils.ImageUtils;
import no.nordicsemi.android.blinky.utils.Qr;
import no.nordicsemi.android.blinky.wekeupble.WakeupManager;
import no.nordicsemi.android.blinky.wekeupble.WakeupManagerCallbacks;

@SuppressWarnings("ConstantConditions")
public class WakeupActivity extends AppCompatActivity implements WakeupManagerCallbacks {
    public static final String EXTRA_DEVICE = "no.nordicsemi.android.blinky.EXTRA_DEVICE";
    public static final String TAG = WakeupActivity.class.getSimpleName();


    @BindView(R.id.qr)
    ImageView qr;
    @BindView(R.id.bt_send)
    Button btSend;
    private String deviceName;
    private String deviceAddress;
    private Bitmap qrCodeBitmap;
    private WakeupManager wakeupManager;
    private int width = 80;
    private int heitht = 80;
    private int reqid;
    private ArrayList<byte[]> totalData;
    private ProgressDialog dialog;

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_qr);
        ButterKnife.bind(this);

        final Intent intent = getIntent();
        final DiscoveredBluetoothDevice device = intent.getParcelableExtra(EXTRA_DEVICE);
        deviceName = device.getName();
        deviceAddress = device.getAddress();

        final Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setTitle(deviceName);
        getSupportActionBar().setSubtitle(deviceAddress);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);


        wakeupManager = new WakeupManager(this);
        wakeupManager.setGattCallbacks(this);

        wakeupManager.connect(device.getDevice())
                .useAutoConnect(false)
                .retry(3, 100)
                .enqueue();


    }


    @Override
    public void onDataReceived(BluetoothDevice device, Data data) {
        List<Integer> datas = DataHandlerUtils.bytesToArrayList(data.getValue());
        if (datas.get(4) == 0x87) {
            if (datas.get(5) == 1) {
                //可以开始发二维码图片
                if (reqid == 0) {
                    sendData();
                }
                //发送完成
                if (reqid != 0) {
                    btSend.setEnabled(true);
                    Toast.makeText(WakeupActivity.this,"发送完成",Toast.LENGTH_SHORT).show();
                }
                reqid = 0;

            }
        }
        if (datas.get(4) == 0x88) {
            reqid = datas.get(5);   //应答序列号
            sendData();
        }

    }

    @Override
    public void onDataSent(BluetoothDevice device, Data data) {
        Log.i(TAG, "onDataSent-->" + DataHandlerUtils.bytesToHexStr(data.getValue()));

    }

    @Override
    public void onDataSent1(BluetoothDevice device, Data data) {
        Log.i(TAG, "onDataSent1-->" + DataHandlerUtils.bytesToHexStr(data.getValue()));

    }

    @Override
    public void onDataSent2(BluetoothDevice device, Data data) {
        Log.i(TAG, "onDataSent2-->" + DataHandlerUtils.bytesToHexStr(data.getValue()));

    }

    @Override
    public void onDeviceConnecting(@NonNull BluetoothDevice device) {
        Log.i(TAG, "onDeviceConnecting");
        showDialog();

    }


    @Override
    public void onDeviceConnected(@NonNull BluetoothDevice device) {
        Log.i(TAG, "onDeviceConnected");

    }

    @Override
    public void onDeviceDisconnecting(@NonNull BluetoothDevice device) {
        Log.i(TAG, "onDeviceDisconnecting");

    }

    @Override
    public void onDeviceDisconnected(@NonNull BluetoothDevice device) {
        Log.i(TAG, "onDeviceDisconnected");
        btSend.setEnabled(false);
        hideDialog();

    }

    @Override
    public void onLinkLossOccurred(@NonNull BluetoothDevice device) {
        Log.i(TAG, "onLinkLossOccurred");

    }

    @Override
    public void onServicesDiscovered(@NonNull BluetoothDevice device, boolean optionalServicesFound) {
        Log.i(TAG, "onServicesDiscovered");

    }

    @Override
    public void onDeviceReady(@NonNull BluetoothDevice device) {
        Log.i(TAG, "onDeviceReady");
        showQRcode();
        btSend.setEnabled(true);
        btSend.setVisibility(View.VISIBLE);
        hideDialog();


    }


    @Override
    public void onBondingRequired(@NonNull BluetoothDevice device) {
        Log.i(TAG, "onBondingRequired");

    }

    @Override
    public void onBonded(@NonNull BluetoothDevice device) {
        Log.i(TAG, "onBonded");

    }

    @Override
    public void onBondingFailed(@NonNull BluetoothDevice device) {
        Log.i(TAG, "onBondingFailed");

    }

    @Override
    public void onError(@NonNull BluetoothDevice device, @NonNull String message, int errorCode) {
        Log.i(TAG, "onError");
        hideDialog();
    }

    @Override
    public void onDeviceNotSupported(@NonNull BluetoothDevice device) {
        Log.i(TAG, "onDeviceNotSupported");
        hideDialog();

    }


    @Override
    protected void onStop() {
        super.onStop();
        if (wakeupManager != null) {
            Log.d(TAG, "onStop--> disconnect");
            wakeupManager.disconnect().enqueue();
        }
    }


    /**
     * 显示二维码
     */
    private void showQRcode() {
        String qrContent = deviceName + deviceAddress;
        String s = qrContent.replaceAll(":", "");

        int size = getResources().getDimensionPixelSize(R.dimen.bitmap_dialog_qr_size);
        qrCodeBitmap = Qr.bitmap(s, size);
        qr.setImageBitmap(qrCodeBitmap);

//        Log.i(TAG, "bitmapSize:" + BitmapUtils.getBitmapSize(qrCodeBitmap) + "\nwidth:" + qrCodeBitmap.getWidth() + "\nheight:" +
//                qrCodeBitmap.getHeight());
        Bitmap scale = ImageUtils.scale(qrCodeBitmap, 80, 80);
//        Log.i(TAG, "bitmapSize:" + BitmapUtils.getBitmapSize(scale) + "\nwidth:" + scale.getWidth() + "\nheight:" +
//                scale.getHeight());

        //获取数据
        totalData = getData(scale);


    }

    private void sendData() {
        byte[] data_to_send = totalData.get(reqid);
        wakeupManager.send(sendQrcodecontent(reqid, data_to_send));
    }

    private ArrayList<byte[]> getData(Bitmap scale) {
        //获取data
        int[] pixels = new int[80 * 80];
        scale.getPixels(pixels, 0, 80, 0, 0, 80, 80);
//        Log.i(TAG, "所有像素：" + Arrays.toString(pixels));
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < pixels.length; i++) {
            if (pixels[i] == -16777216) {
                builder.append("0");
            } else {
                builder.append("1");
            }
        }
        String content = builder.toString();
//        Log.v(TAG, "所有像素2：" + builder.toString());
        byte[] data = new byte[pixels.length / 8];
        for (int i = 0, j = 0; i < content.length(); i++, j++) {
            char a0 = content.charAt(i);
            char a1 = content.charAt(i + width);
            char a2 = content.charAt(i + width * 2);
            char a3 = content.charAt(i + width * 3);
            char a4 = content.charAt(i + width * 4);
            char a5 = content.charAt(i + width * 5);
            char a6 = content.charAt(i + width * 6);
            char a7 = content.charAt(i + width * 7);
            String buf = "" + a7 + a6 + a5 + a4 + a3 + a2 + a1 + a0;
            data[j] = (byte) (Integer.parseInt(buf, 2));
            if ((i + 1) % width == 0 && i > 0) {
                i = i + width * 7;
            }
        }
        ArrayList<byte[]> results = BitmapUtils.SplitList(data, 14);
        return results;
    }


    /**
     * 发送二维码
     *
     * @param view
     */
    public void send(View view) {
        wakeupManager.send(sendQrcode(1));
        btSend.setEnabled(false);

    }


    /**
     * 控制发送二维码图片
     *
     * @param control
     */
    public byte[] sendQrcode(int control) {
        byte[] bytes = new byte[6];
        bytes[0] = (byte) 0xAB;
        bytes[1] = (byte) 0;
        bytes[2] = (byte) 3;
        bytes[3] = (byte) 0xFF;
        bytes[4] = (byte) 0x87;
        bytes[5] = (byte) control;
        return bytes;
    }

    /**
     * 发送二维码图片信息
     *
     * @param req  序列号
     * @param data 字节数据
     */
    public byte[] sendQrcodecontent(int req, byte[] data) {
        int length = data.length;
        byte[] bytes = new byte[6];
        bytes[0] = (byte) 0xAB;
        bytes[1] = (byte) 0;
        bytes[2] = (byte) (length + 3);
        bytes[3] = (byte) 0xFF;
        bytes[4] = (byte) 0x88;
        bytes[5] = (byte) req;    //最大为255个数据包
        byte[] bytes2 = BitmapUtils.addBytes(bytes, data);
        return bytes2;
    }


    private void showDialog() {
        if (dialog==null) {
            dialog = new ProgressDialog(this);
            dialog.show();
            Log.d(TAG,"showDialog");
        }


    }

    @Override
    public void onDataReceived3(BluetoothDevice device, Data data) {

    }

    @Override
    public void onDataReceived4(BluetoothDevice device, Data data) {

    }

    private void hideDialog() {
        if (dialog != null && dialog.isShowing()){
            dialog.dismiss();
            Log.d(TAG,"hideDialog");
        }
    }
}
